package io.renren.modules.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import io.renren.modules.netty.codec.SocketDecoder;
import io.renren.modules.netty.codec.SocketEncoder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * netty客户端
 * @author lenovo
 *
 */
//@Component
@Slf4j
public class NettyClient {
	private final static String HOST = "iot.wznhjc.cn";
	private final static int PORT = 8191;
	private final static int READER_IDLE_TIME_SECONDS = 0;//读操作空闲20秒
	private final static int WRITER_IDLE_TIME_SECONDS = 5;//写操作空闲20秒
	private final static int ALL_IDLE_TIME_SECONDS = 0;//读写全部空闲40秒

	private EventLoopGroup loop = new NioEventLoopGroup();

	public NioEventLoopGroup workerGroup() {
		return new NioEventLoopGroup();
	}
	/**
	 * netty client 连接，连接失败5秒后重试连接
	 */
//	@PostConstruct
	public Bootstrap bootstrap() {
		Bootstrap bootstrap = new Bootstrap();
		EventLoopGroup eventLoopGroup = workerGroup();
		try {
			if (bootstrap != null) {
				bootstrap.group(eventLoopGroup);
				bootstrap.channel(NioSocketChannel.class);
				bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
				bootstrap.handler(new ChannelInitializer<SocketChannel>() {
					@Override
					public void initChannel(SocketChannel ch) throws Exception {
						ChannelPipeline pipeline = ch.pipeline();

						pipeline.addLast("idleStateHandler", new IdleStateHandler(READER_IDLE_TIME_SECONDS
								, WRITER_IDLE_TIME_SECONDS, ALL_IDLE_TIME_SECONDS, TimeUnit.SECONDS));

						pipeline.addLast(new SocketDecoder());
						pipeline.addLast(new SocketEncoder());

						pipeline.addLast("clientHandler", new LogicClientHandler(NettyClient.this));
//						pipeline.addLast("idleTimeoutHandler", new HeartHandler(NettyClient.this));
					}
				});
				bootstrap.remoteAddress(HOST, PORT);
				ChannelFuture f = bootstrap.connect().addListener((ChannelFuture futureListener)->{
					final EventLoop eventLoop = futureListener.channel().eventLoop();
					if (!futureListener.isSuccess()) {
						log.warn("连接服务器失败，5s后重新尝试连接！");
						futureListener.channel().eventLoop().schedule(() -> bootstrap(), 5, TimeUnit.SECONDS);
					}
				});
				f.channel().closeFuture().sync();
				//eventLoopGroup.shutdownGracefully();
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			e.printStackTrace();
		}
		return bootstrap;
	}
}
